package com.szcinda.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.Sheet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.szcinda.controller.configuration.UserLoginToken;
import com.szcinda.controller.excelUtil.GsonUtil;
import com.szcinda.controller.params.QueryDto;
import com.szcinda.repository.*;
import com.szcinda.service.PageResult;
import com.szcinda.service.TypeStringUtils;
import com.szcinda.service.dto.calculatePrice.CalculateDto;
import com.szcinda.service.dto.calculatePrice.CalculateService;
import com.szcinda.service.dto.calculatePrice.PriceDto;
import com.szcinda.service.dto.customColumns.CustomColumnsService;
import com.szcinda.service.dto.ghOrder.*;
import com.szcinda.service.dto.history.GhOrderExportVo;
import com.szcinda.service.dto.history.ZadOrderExportVo;
import com.szcinda.service.dto.log.ExportCountService;
import com.szcinda.service.dto.log.ExportLogService;
import com.szcinda.service.dto.log.OperateOrderDto;
import com.szcinda.service.dto.zadOrder.ReCalculateFeeParams;
import com.szcinda.service.dto.zadOrder.ZadOrderTransportFeeImportListener;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.szcinda.controller.ZadOrderController.*;
import static java.nio.charset.StandardCharsets.UTF_8;

@RestController
@RequestMapping("ghOrder")
public class GhOrderController {

    @Value("${upload.file.path}")
    private String filePath;
    @Value("${execute.file.path}")
    private String executeFilePath;
    @Value("${execute.python.path}")
    private String pythonPath;
    private final GhOrderService ghOrderService;
    private final CalculateService calculateService;
    private final ExportLogService exportLogService;
    private final CustomColumnsService customColumnsService;
    private final BankInfoRepository bankInfoRepository;
    private final ExportCountService exportCountService;
    private final UserRepository userRepository;
    private final FeeItemRepository feeItemRepository;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public GhOrderController(GhOrderService ghOrderService, CalculateService calculateService,
                             ExportLogService exportLogService, CustomColumnsService customColumnsService,
                             BankInfoRepository bankInfoRepository, ExportCountService exportCountService,
                             UserRepository userRepository, FeeItemRepository feeItemRepository) {
        this.ghOrderService = ghOrderService;
        this.calculateService = calculateService;
        this.exportLogService = exportLogService;
        this.customColumnsService = customColumnsService;
        this.bankInfoRepository = bankInfoRepository;
        this.exportCountService = exportCountService;
        this.userRepository = userRepository;
        this.feeItemRepository = feeItemRepository;
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        objectMapper.registerModule(javaTimeModule);
    }


    @UserLoginToken
    @PostMapping("create")
    @OperationLogAnnotation(operDesc = "新增综合物流订单", operModel = "综合物流")
    public Result<String> create(@RequestBody GhOrderCreateDto createDto) {
        ghOrderService.create(createDto);
        return Result.success();
    }

    @UserLoginToken
    @PostMapping("modify")
    @OperationLogAnnotation(operDesc = "修改综合物流订单", operModel = "综合物流")
    public Result<String> modify(@RequestBody GhOrderUpdateDto updateDto) {
        ghOrderService.update(updateDto);
        return Result.success();
    }

    @PostMapping("changeInvoice/{type}/{opId}")
    @OperationLogAnnotation(operDesc = "修改综合物流订单", operModel = "综合物流")
    public Result<String> changeInvoice(@RequestBody List<String> orderIds, @PathVariable String type, @PathVariable String opId) {
        ghOrderService.changeInvoice(orderIds, type, opId, null);
        return Result.success();
    }

    @PostMapping("changeSettlement/{type}/{opId}")
    @OperationLogAnnotation(operDesc = "修改综合物流订单", operModel = "综合物流")
    public Result<String> changeSettlement(@RequestBody List<String> orderIds, @PathVariable String type, @PathVariable String opId) {
        ghOrderService.changeSettlement(orderIds, type, opId, null);
        return Result.success();
    }

    @GetMapping("feeList/{id}")
    public Result<List<OrderFee>> feeList(@PathVariable String id) {
        return Result.success(ghOrderService.getFeeListById(id));
    }


    @PostMapping("reCalculateFee")
    public Result<String> reCalculateFee(@RequestBody List<String> ids) {
        ghOrderService.reCalculateFee(ids);
        return Result.success();
    }

    @PostMapping("reCalculateFeeById")
    public Result<String> reCalculateFeeById(@RequestBody ReCalculateFeeParams params) {
        ghOrderService.reCalculateFeeById(params);
        return Result.success();
    }

    @GetMapping("getById/{id}")
    public Result<GhOrderDto> getById(@PathVariable String id) {
        return Result.success(ghOrderService.getById(id));
    }

    @UserLoginToken
    @PostMapping("modifyPart")
    @OperationLogAnnotation(operDesc = "修改综合物流订单")
    public Result<String> modifyPart(@RequestBody GhOrderUpdatePartDto updateDto) {
        ghOrderService.update(updateDto);
        return Result.success();
    }


    @GetMapping("del/{id}/{userId}")
    @OperationLogAnnotation(operDesc = "删除综合物流订单", operModel = "综合物流")
    public Result<String> delete(@PathVariable String id, @PathVariable String userId) {
        ghOrderService.delete(id, userId);
        return Result.success();
    }


    @PostMapping("query")
    public PageResult<GhOrderDto> query(@RequestBody GhOrderQueryDto queryDto) {
        return ghOrderService.query(queryDto);
    }

    @PostMapping("/import/{opId}")
    @OperationLogAnnotation(operDesc = "导入综合物流订单", operModel = "综合物流")
    public Result<?> orderImport(@RequestParam("file") MultipartFile file, @PathVariable String opId) throws Exception {
        // 解析每行结果在listener中处理
        InputStream inputStream = file.getInputStream();
        try {
            GhOrderExcelListener listener = new GhOrderExcelListener();
            EasyExcelFactory.readBySax(inputStream, new Sheet(1, 1, GhOrderImportDto.class), listener);
            return ghOrderService.batchCreate(listener.getImportDatas(), opId);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    @PostMapping("export")
    @OperationLogAnnotation(operDesc = "导出综合物流订单", operModel = "综合物流")
    public void export(@RequestParam(required = false) String actDepartureTimeStart,
                       @RequestParam(required = false) String actDepartureTimeEnd,
                       @RequestParam(required = false) String createTimeStart,
                       @RequestParam(required = false) String createTimeEnd,
                       @RequestParam(required = false) String receiveDateStart,
                       @RequestParam(required = false) String receiveDateEnd,
                       @RequestParam(required = false) String pickDateStart,
                       @RequestParam(required = false) String pickDateEnd,
                       @RequestParam(required = false) String carrierId,
                       @RequestParam(required = false) String clientId,
                       @RequestParam(required = false) String organizationId,
                       @RequestParam(required = false) String bookNumber,
                       @RequestParam String userId,
                       @RequestParam String columns, HttpServletResponse response) throws Exception {
        Assert.isTrue(StringUtils.hasText(columns), "请先保存自定义列再导出");
        OutputStream out = response.getOutputStream();
        GhOrderQueryDto params = new GhOrderQueryDto();
        if (StringUtils.hasText(actDepartureTimeStart)) {
            params.setActDepartureTimeStart(LocalDate.parse(actDepartureTimeStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(actDepartureTimeEnd)) {
            params.setActDepartureTimeEnd(LocalDate.parse(actDepartureTimeEnd, dateTimeFormatter));
        }
        if (StringUtils.hasText(createTimeStart)) {
            params.setCreateTimeStart(LocalDate.parse(createTimeStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(createTimeEnd)) {
            params.setCreateTimeEnd(LocalDate.parse(createTimeEnd, dateTimeFormatter));
        }

        if (StringUtils.hasText(receiveDateStart)) {
            params.setReceiveDateStart(LocalDate.parse(receiveDateStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(receiveDateEnd)) {
            params.setReceiveDateEnd(LocalDate.parse(receiveDateEnd, dateTimeFormatter));
        }
        if (StringUtils.hasText(pickDateStart)) {
            params.setPickDateStart(LocalDate.parse(pickDateStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(pickDateEnd)) {
            params.setPickDateEnd(LocalDate.parse(pickDateEnd, dateTimeFormatter));
        }
        User user = userRepository.findById(userId);
        if (StringUtils.isEmpty(organizationId)) {
            organizationId = user.getOrganizationId();
        }
        params.setClientId(clientId);
        params.setCarrierId(carrierId);
        params.setBookNumber(bookNumber);
        params.setUserId(userId);
        params.setOrganizationId(organizationId);
        List<GhOrderDto> ghOrderDtos = ghOrderService.queryAll(params);
        Map<String, String> fieldMap = GhOrderDto.getFieldMap();
        String[] columnsArray = columns.split(",");
        List<String> columnList;
        if (columnsArray.length == 0) {
            columnList = new ArrayList<>(fieldMap.keySet());
        } else {
            columnList = new ArrayList<>(Arrays.asList(columnsArray));
        }

        Map<String, List<String>> map = new HashMap<>();
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("sheet1");
        sheet.setDefaultColumnWidth(20);// 默认列宽
        HSSFRow row = sheet.createRow(0);
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        HSSFCell cell;
        // 生成标题
        int size = columnList.size();
        for (int i = 0; i < size; i++) {
            cell = row.createCell((short) i);
            cell.setCellValue(columnList.get(i));
            cell.setCellStyle(style);
        }
        for (GhOrderDto dto : ghOrderDtos) {
            String id = dto.getId();
            List<String> list = new ArrayList<>();
            columnList.forEach(column -> {
                if (fieldMap.containsKey(column)) {
                    String value;
                    try {
                        Field field = GhOrderDto.class.getDeclaredField(fieldMap.get(column));
                        if (field.getType() == String.class) {
                            value = (String) field.get(dto);
                            if ("计费方式".equals(column)) {
                                value = getCalculateString(value);
                            }
                        } else if (field.getType() == Integer.class || field.getGenericType().getTypeName().equals("int")) {
                            value = ((Integer) field.get(dto)).toString();
                        } else if (field.getType() == Double.class || field.getGenericType().getTypeName().equals("double")) {
                            value = field.get(dto).toString();
                        } else if (field.getType() == LocalDateTime.class) {
                            value = ((LocalDateTime) field.get(dto)).toString().replace("T", " ");
                        } else if (field.getType() == LocalDate.class) {
                            value = ((LocalDate) field.get(dto)).toString();
                        } else {
                            value = "";
                        }
                    } catch (Exception e) {
                        value = "";
                    }
                    if ("重泡比".equals(column)) {
                        value = "1:" + value;
                    }
                    if (value == null) {
                        value = "";
                    }
                    list.add(value);
                }
            });
            map.put(id, list);
        }
        int i = 0;
        for (GhOrderDto dto : ghOrderDtos) {
            row = sheet.createRow(i + 1);
            List<String> list = map.get(dto.getId());
            for (int j = 0; j < size; j++) {
                try {
                    row.createCell((short) j).setCellValue(list.get(j));
                } catch (Exception exception) {
                }
            }
            i++;
        }
        // 下载EXCEL
        String fName = URLEncoder.encode("综合物流-" + LocalDateTime.now().format(dateTimeFormatter2), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fName + ".xls");
        wb.write(out);
        out.flush();
    }

    @PostMapping("exportTransportFee")
    @OperationLogAnnotation(operDesc = "导出综合物流运费", operModel = "综合物流")
    public void exportTransportFee(@RequestParam(required = false) String actDepartureTimeStart,
                                   @RequestParam(required = false) String actDepartureTimeEnd,
                                   @RequestParam(required = false) String createTimeStart,
                                   @RequestParam(required = false) String createTimeEnd,
                                   @RequestParam(required = false) String receiveDateStart,
                                   @RequestParam(required = false) String receiveDateEnd,
                                   @RequestParam(required = false) String pickDateStart,
                                   @RequestParam(required = false) String pickDateEnd,
                                   @RequestParam(required = false) String carrierId,
                                   @RequestParam(required = false) String clientId,
                                   @RequestParam(required = false) String organizationId,
                                   @RequestParam(required = false) String bookNumber,
                                   @RequestParam String userId,
                                   @RequestParam String columns, HttpServletResponse response) throws Exception {
        Assert.isTrue(StringUtils.hasText(columns), "请先保存自定义列再导出");
        GhOrderQueryDto params = new GhOrderQueryDto();
        if (StringUtils.hasText(actDepartureTimeStart)) {
            params.setActDepartureTimeStart(LocalDate.parse(actDepartureTimeStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(actDepartureTimeEnd)) {
            params.setActDepartureTimeEnd(LocalDate.parse(actDepartureTimeEnd, dateTimeFormatter));
        }
        if (StringUtils.hasText(createTimeStart)) {
            params.setCreateTimeStart(LocalDate.parse(createTimeStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(createTimeEnd)) {
            params.setCreateTimeEnd(LocalDate.parse(createTimeEnd, dateTimeFormatter));
        }

        if (StringUtils.hasText(receiveDateStart)) {
            params.setReceiveDateStart(LocalDate.parse(receiveDateStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(receiveDateEnd)) {
            params.setReceiveDateEnd(LocalDate.parse(receiveDateEnd, dateTimeFormatter));
        }
        if (StringUtils.hasText(pickDateStart)) {
            params.setPickDateStart(LocalDate.parse(pickDateStart, dateTimeFormatter));
        }
        if (StringUtils.hasText(pickDateEnd)) {
            params.setPickDateEnd(LocalDate.parse(pickDateEnd, dateTimeFormatter));
        }
        User user = userRepository.findById(userId);
        if (StringUtils.isEmpty(organizationId)) {
            organizationId = user.getOrganizationId();
        }
        params.setClientId(clientId);
        params.setCarrierId(carrierId);
        params.setBookNumber(bookNumber);
        params.setUserId(userId);
        params.setOrganizationId(organizationId);
        List<GhOrderDto> ghOrderDtos = ghOrderService.queryAll(params);
        List<GhOrderExportVo> exportVos = new ArrayList<>();
        List<OrderFee> orderFeeList =
                ghOrderService.getFeeListByIdIn(ghOrderDtos.stream().map(GhOrderDto::getId).collect(Collectors.toList()));
        String fileName = String.format("班列运费-%s.xlsx", LocalDateTime.now().toLocalTime().toString());
        //HttpServletResponse消息头参数设置
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Transfer-Encoding", "binary");
        response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
        fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        for (GhOrderDto ghOrderDto : ghOrderDtos) {
            GhOrderExportVo vo = new GhOrderExportVo();
            BeanUtils.copyProperties(ghOrderDto, vo);
            orderFeeList.stream().filter(fee -> TypeStringUtils.feeInType.equals(fee.getType()) && ghOrderDto.getId().equals(fee.getOrderId()) && TypeStringUtils.TRANSPORT_FEE.equals(fee.getFeeName()))
                    .findFirst()
                    .ifPresent(fee -> {
                        vo.setInCurrency(fee.getCurrency());
                        vo.setTransportFee(fee.getFeeCount());
                    });
            orderFeeList.stream().filter(fee -> TypeStringUtils.feeOutType.equals(fee.getType()) && ghOrderDto.getId().equals(fee.getOrderId()) && TypeStringUtils.TRANSPORT_FEE.equals(fee.getFeeName()))
                    .findFirst()
                    .ifPresent(fee -> {
                        vo.setOutCurrency(fee.getCurrency());
                        vo.setOutTransportFee(fee.getFeeCount());
                        vo.setCarrier(fee.getCarrierId());
                    });
            exportVos.add(vo);
        }
        EasyExcel.write(response.getOutputStream(), GhOrderExportVo.class).sheet("综合运费").doWrite(exportVos);
    }


    @PostMapping("exportBySelect")
    @OperationLogAnnotation(operDesc = "导出综合物流订单", operModel = "综合物流")
    public void export(@RequestParam(required = false) String ids,
                       @RequestParam String columns, HttpServletResponse response) throws Exception {
        Assert.isTrue(StringUtils.hasText(columns), "请先保存自定义列再导出");
        OutputStream out = response.getOutputStream();
        List<GhOrderDto> ghOrderDtos = ghOrderService.getAllByIds(Arrays.asList(ids.split(",")));
        Map<String, String> fieldMap = GhOrderDto.getFieldMap();
        String[] columnsArray = columns.split(",");
        List<String> columnList;
        if (columnsArray.length == 0) {
            columnList = new ArrayList<>(fieldMap.keySet());
        } else {
            columnList = new ArrayList<>(Arrays.asList(columnsArray));
        }
        Map<String, List<String>> map = new HashMap<>();
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("sheet1");
        sheet.setDefaultColumnWidth(20);// 默认列宽
        HSSFRow row = sheet.createRow(0);
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        HSSFCell cell;
        // 生成标题
        int size = columnList.size();
        for (int i = 0; i < size; i++) {
            cell = row.createCell((short) i);
            cell.setCellValue(columnList.get(i));
            cell.setCellStyle(style);
        }
        for (GhOrderDto dto : ghOrderDtos) {
            String id = dto.getId();
            List<String> list = new ArrayList<>();
            columnList.forEach(column -> {
                if (fieldMap.containsKey(column)) {
                    String value;
                    try {
                        Field field = GhOrderDto.class.getDeclaredField(fieldMap.get(column));
                        if (field.getType() == String.class) {
                            value = (String) field.get(dto);
                            if ("计费方式".equals(column)) {
                                value = getCalculateString(value);
                            }
                        } else if (field.getType() == Integer.class || field.getGenericType().getTypeName().equals("int")) {
                            value = ((Integer) field.get(dto)).toString();
                        } else if (field.getType() == Double.class || field.getGenericType().getTypeName().equals("double")) {
                            value = field.get(dto).toString();
                        } else if (field.getType() == LocalDateTime.class) {
                            value = ((LocalDateTime) field.get(dto)).toString().replace("T", " ");
                        } else if (field.getType() == LocalDate.class) {
                            value = ((LocalDate) field.get(dto)).toString();
                        } else {
                            value = "";
                        }
                    } catch (Exception e) {
                        value = "";
                    }
                    if ("重泡比".equals(column)) {
                        value = "1:" + value;
                    }
                    if (value == null) {
                        value = "";
                    }
                    list.add(value);
                }
            });
            map.put(id, list);
        }
        int i = 0;
        for (GhOrderDto dto : ghOrderDtos) {
            row = sheet.createRow(i + 1);
            List<String> list = map.get(dto.getId());
            for (int j = 0; j < size; j++) {
                try {
                    row.createCell((short) j).setCellValue(list.get(j));
                } catch (Exception exception) {
                }
            }
            i++;
        }
        // 下载EXCEL
        String fName = URLEncoder.encode("综合物流-" + LocalDateTime.now().format(dateTimeFormatter2), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fName + ".xls");
        wb.write(out);
        out.flush();
    }

    @PostMapping("exportTransportFeeBySelect")
    @OperationLogAnnotation(operDesc = "导出综合物流运费", operModel = "综合物流")
    public void exportTransportFeeBySelect(@RequestParam(required = false) String ids, HttpServletResponse response) throws Exception {
        List<GhOrderDto> ghOrderDtos = ghOrderService.getAllByIds(Arrays.asList(ids.split(",")));
        List<GhOrderExportVo> exportVos = new ArrayList<>();
        List<OrderFee> orderFeeList =
                ghOrderService.getFeeListByIdIn(Arrays.asList(ids.split(",")));
        String fileName = String.format("综合运费-%s.xlsx", LocalDateTime.now().toLocalTime().toString());
        //HttpServletResponse消息头参数设置
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Transfer-Encoding", "binary");
        response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
        fileName = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        for (GhOrderDto ghOrderDto : ghOrderDtos) {
            GhOrderExportVo vo = new GhOrderExportVo();
            BeanUtils.copyProperties(ghOrderDto, vo);
            orderFeeList.stream().filter(fee -> TypeStringUtils.feeInType.equals(fee.getType()) && ghOrderDto.getId().equals(fee.getOrderId()) && TypeStringUtils.TRANSPORT_FEE.equals(fee.getFeeName()))
                    .findFirst()
                    .ifPresent(fee -> {
                        vo.setInCurrency(fee.getCurrency());
                        vo.setTransportFee(fee.getFeeCount());
                    });
            orderFeeList.stream().filter(fee -> TypeStringUtils.feeOutType.equals(fee.getType()) && ghOrderDto.getId().equals(fee.getOrderId()) && TypeStringUtils.TRANSPORT_FEE.equals(fee.getFeeName()))
                    .findFirst()
                    .ifPresent(fee -> {
                        vo.setOutCurrency(fee.getCurrency());
                        vo.setOutTransportFee(fee.getFeeCount());
                        vo.setCarrier(fee.getCarrierId());
                    });
            exportVos.add(vo);
        }
        EasyExcel.write(response.getOutputStream(), GhOrderExportVo.class).sheet("综合运费").doWrite(exportVos);
    }

    @PostMapping("lock/{userId}")
    @OperationLogAnnotation(operDesc = "锁定综合物流订单", operModel = "综合物流")
    public Result<String> lock(@PathVariable String userId, @RequestBody List<String> ids) {
        ghOrderService.confirmOrder(ids, userId);
        return Result.success();
    }

    @PostMapping("unlock/{userId}")
    @OperationLogAnnotation(operDesc = "解锁综合物流订单", operModel = "综合物流")
    public Result<String> unlock(@PathVariable String userId, @RequestBody List<String> ids) {
        ghOrderService.unConfirmOrder(ids, userId);
        return Result.success();
    }

    @PostMapping("calculateFee")
    public Result<List<PriceDto>> calculateReceivable(@RequestBody CalculateDto calculateDto) {
        return Result.success(calculateService.calculate(calculateDto));
    }

    @PostMapping("calculateOutFee")
    public Result<List<PriceDto>> calculateOutFee(@RequestBody CalculateDto calculateDto) {
        return Result.success(calculateService.calculateOut(calculateDto));
    }

    @PostMapping("calculateVehicleFee")
    public Result<List<PriceDto>> calculateVehicleFee(@RequestBody CalculateDto calculateDto) {
        return Result.success(calculateService.calculateVehicleFee(calculateDto));
    }

    @PostMapping("partExportByTypeQuery")
    @OperationLogAnnotation(operDesc = "导出综合物流订单", operModel = "综合物流")
    public Result<List<GhOrderDto>> partExportByTypeQuery(@RequestBody QueryDto params) throws Exception {
        String curr = StringUtils.isEmpty(params.getCurrencyType()) ? params.getCurrency() : params.getCurrencyType();
        if (StringUtils.isEmpty(curr)) {
            curr = TypeStringUtils.unTransfer;
        }
        List<GhOrderDto> dtos = ghOrderService.getAllByIds(params.getIds(), params.getType(), curr, params.getRateList());
        double amount = 0;
        boolean noCurrency = false;
        Map<String, Double> sumMap = null;
        if (StringUtils.isEmpty(curr) || TypeStringUtils.unTransfer.equals(curr)) {
            noCurrency = true;
            sumMap = new HashMap<>();
            sumMap.put("无币种", 0d);
        }
        for (GhOrderDto dto : dtos) {
            List<GhOrderDto.FeeDto> feeList = dto.getFeeList();
            for (GhOrderDto.FeeDto feeDto : feeList) {
                if (noCurrency) {
                    if (StringUtils.hasText(feeDto.getCurrency())) {
                        if (sumMap.containsKey(feeDto.getCurrency())) {
                            double sum = sumMap.get(feeDto.getCurrency());
                            sum += feeDto.getFeeCount();
                            sumMap.put(feeDto.getCurrency(), sum);
                        } else {
                            sumMap.put(feeDto.getCurrency(), feeDto.getFeeCount());
                        }
                    } else {
                        double sum = sumMap.get("无币种");
                        sum += feeDto.getFeeCount();
                        sumMap.put("无币种", sum);
                    }
                } else {
                    amount += feeDto.getFeeCount();
                }
            }
            // 转换计费方式
            dto.setCalculateType(getCalculateString(dto.getCalculateType()));
        }
        StringBuilder sumText = new StringBuilder();
        if (noCurrency) {
            // 去除0
            double no = sumMap.get("无币种");
            if (no == 0) {
                sumMap.remove("无币种");
            }
            Set<String> keySet = sumMap.keySet();
            for (String key : keySet) {
                sumText.append(sumMap.get(key)).append(key).append(";");
            }
        } else {
            sumText.append(Double.valueOf(String.format("%.2f", amount))).append(curr);
        }
        // 保存导出记录
        ExportLog exportLog = new ExportLog();
        exportLog.setCurrency(curr);
        // 汇率
        if (!TypeStringUtils.unTransfer.equals(exportLog.getCurrency()) && params.getRateList() != null) {
            List<String> rateStrList = new ArrayList<>();
            params.getRateList().forEach(ex -> {
                if (ex.getToRate().equals(exportLog.getCurrency())) {
                    if (!rateStrList.contains(ex.getRate() + "")) {
                        rateStrList.add(ex.getRate() + "");
                    }
                }
            });
            if (rateStrList.size() > 0) {
                exportLog.setCurrency(curr + "(汇率：" + rateStrList.get(0) + ")");
            }
        }
        StringBuilder description = new StringBuilder();
        Set<String> orgNames = dtos.stream().map(GhOrderDto::getOrganizationName).collect(Collectors.toSet());
        if (TypeStringUtils.feeInType.equals(params.getType())) {
            Set<String> clientNames = dtos.stream().map(GhOrderDto::getClientName).collect(Collectors.toSet());
            description.append("机构：").append(String.join(",", orgNames)).append("。客户：").append(String.join(",", clientNames))
                    .append("。费用项：")
                    .append(String.join(",", params.getExportFeeNames())).append("。总金额：").append(sumText.toString());
        } else {
            Set<String> carrierNames = new HashSet<>();
            String name;
            for (GhOrderDto dto : dtos) {
                name = dto.getCarrierName();
                String[] names = name.split(",");
                carrierNames.addAll(Arrays.asList(names));
            }
            description.append("机构：").append(String.join(",", orgNames)).append("。供应商：").append(String.join(",", carrierNames)).append("。费用项：")
                    .append(String.join(",", params.getExportFeeNames())).append("。总金额：").append(sumText.toString());
        }
        exportLog.setColumns(description.toString());
        exportLog.setTableName(params.getTableName());
        exportLog.setType(params.getType());
        exportLog.setUserId(params.getUserId());
        exportLog.setFileName(new File(params.getExcelPath()).getName());
        exportLog.setIds(dtos.stream().map(GhOrderDto::getId).collect(Collectors.joining(",")));
        exportLogService.create(exportLog);
        return Result.success(dtos);
    }

    @PostMapping("partExportByType3")
    @OperationLogAnnotation(operDesc = "导出综合物流订单", operModel = "综合物流")
    public Result<String> partExportByType3(@RequestBody QueryDto params) throws Exception {
        Map<String, String> fieldMap = GhOrderDto.getFieldMap();
        String columns = customColumnsService.getColumnsByUser(params.getUserId(), params.getTableName());
        Assert.isTrue(StringUtils.hasText(columns), "请先保存自定义列再导出");
        List<String> feeNameList = customColumnsService.getFeeNameList();
        params.setFieldMap(fieldMap);
        params.setFeeNames(feeNameList);
        params.setExportColumns(columns);
        // 额外信息
        String yearMonth = LocalDate.now().format(dateTimeFormatter3);
        String exportProfitType;
        if (TypeStringUtils.feeInType.equals(params.getType())) {
            BankInfo bankInfo = bankInfoRepository.findFirstById(params.getBankInfoId());
            params.getExt().put("bankAccountName", "深圳星达国际供应链科技有限公司");
            params.getExt().put("company1Eng", "Shenzhen Cinda International Supply Chain Technology Co., Ltd.");
            // 公司名称
            params.getExt().put("rmbCompany", bankInfo.getMark());
            params.getExt().put("usdCompany", "");
            // 开户行
            params.getExt().put("rmbBankName", bankInfo.getRmbBankName());
            params.getExt().put("usdBankName", bankInfo.getUsdBankName());
            // 账号
            params.getExt().put("rmbBankAccount", bankInfo.getRmbAccount());
            params.getExt().put("usdBankAccount", bankInfo.getUsdAccount());
            exportProfitType = "exportGhOrderReceivable";
        } else {
            exportProfitType = "exportGhOrderPayable";
        }
        int count = exportCountService.getNextNumber(yearMonth, exportProfitType);
        params.getExt().put("invoiceNo", yearMonth + String.format("%03d", count));
        params.getExt().put("date", LocalDate.now().format(dateTimeFormatter));
        // 汇率
        if (!TypeStringUtils.unTransfer.equals(params.getCurrency()) && params.getRateList() != null) {
            List<String> rateStrList = new ArrayList<>();
            params.getRateList().forEach(ex -> {
                if (ex.getToRate().equals(params.getCurrency())) {
                    if (!rateStrList.contains(ex.getRate() + "")) {
                        rateStrList.add(ex.getRate() + "");
                    }
                }
            });
            if (rateStrList.size() > 0) {
                params.setRate(rateStrList.get(0));
            }
        }
        // 保存导出记录
        String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String fileName = "账单-" + date + ".xlsx";
        params.setExcelPath(filePath + "\\" + fileName);
        params.setApi("http://localhost:9045/api/ghOrder/partExportByTypeQuery");
        System.out.println(GsonUtil.toJsonString(objectMapper.writeValueAsString(params)));
        //这个方法是类似隐形开启了命令执行器，输入指令执行python脚本
        Process process = Runtime.getRuntime()
                .exec(pythonPath + " " + executeFilePath + " " + GsonUtil.toJsonString(objectMapper.writeValueAsString(params)));
        //这种方式获取返回值的方式是需要用python打印输出，然后java去获取命令行的输出，在java返回
        InputStreamReader ir = new InputStreamReader(process.getInputStream(), UTF_8);
        LineNumberReader input = new LineNumberReader(ir);
        String filePath = input.readLine();
        input.close();
        ir.close();
        process.waitFor();
        if (filePath == null) {
            return Result.fail("生成报表失败");
        }
        return Result.success(new File(filePath).getName());
    }


    @PostMapping("exportByTypeQuery")
    @OperationLogAnnotation(operDesc = "导出综合物流订单", operModel = "综合物流")
    public Result<List<GhOrderDto>> exportByTypeQuery(@RequestBody QueryDto params) throws Exception {
        String curr = StringUtils.isEmpty(params.getCurrencyType()) ? params.getCurrency() : params.getCurrencyType();
        if (StringUtils.isEmpty(curr)) {
            curr = TypeStringUtils.unTransfer;
        }
        params.setCurrency(curr);
        List<GhOrderDto> dtos = ghOrderService.query(params);
        double amount = 0;
        boolean noCurrency = false;
        Map<String, Double> sumMap = null;
        if (StringUtils.isEmpty(curr) || TypeStringUtils.unTransfer.equals(curr)) {
            noCurrency = true;
            sumMap = new HashMap<>();
            sumMap.put("无币种", 0d);
        }
        for (GhOrderDto dto : dtos) {
            List<GhOrderDto.FeeDto> feeList = dto.getFeeList();
            for (GhOrderDto.FeeDto feeDto : feeList) {
                if (noCurrency) {
                    if (StringUtils.hasText(feeDto.getCurrency())) {
                        if (sumMap.containsKey(feeDto.getCurrency())) {
                            double sum = sumMap.get(feeDto.getCurrency());
                            sum += feeDto.getFeeCount();
                            sumMap.put(feeDto.getCurrency(), sum);
                        } else {
                            sumMap.put(feeDto.getCurrency(), feeDto.getFeeCount());
                        }
                    } else {
                        double sum = sumMap.get("无币种");
                        sum += feeDto.getFeeCount();
                        sumMap.put("无币种", sum);
                    }
                } else {
                    amount += feeDto.getFeeCount();
                }
            }
            // 转换计费方式
            dto.setCalculateType(getCalculateString(dto.getCalculateType()));
        }
        StringBuilder sumText = new StringBuilder();
        if (noCurrency) {
            // 去除0
            double no = sumMap.get("无币种");
            if (no == 0) {
                sumMap.remove("无币种");
            }
            Set<String> keySet = sumMap.keySet();
            for (String key : keySet) {
                sumText.append(sumMap.get(key)).append(key).append(";");
            }
        } else {
            sumText.append(Double.valueOf(String.format("%.2f", amount))).append(curr);
        }
        // 保存导出记录
        ExportLog exportLog = new ExportLog();
        exportLog.setCurrency(curr);
        // 汇率
        if (!TypeStringUtils.unTransfer.equals(exportLog.getCurrency()) && params.getRateList() != null) {
            List<String> rateStrList = new ArrayList<>();
            params.getRateList().forEach(ex -> {
                if (ex.getToRate().equals(exportLog.getCurrency())) {
                    if (!rateStrList.contains(ex.getRate() + "")) {
                        rateStrList.add(ex.getRate() + "");
                    }
                }
            });
            if (rateStrList.size() > 0) {
                exportLog.setCurrency(curr + "(汇率：" + rateStrList.get(0) + ")");
            }
        }
        StringBuilder description = new StringBuilder();
        Set<String> orgNames = dtos.stream().map(GhOrderDto::getOrganizationName).collect(Collectors.toSet());
        if (TypeStringUtils.feeInType.equals(params.getType())) {
            Set<String> clientNames = dtos.stream().map(GhOrderDto::getClientName).collect(Collectors.toSet());
            description.append("机构：").append(String.join(",", orgNames)).append("。客户：").append(String.join(",", clientNames))
                    .append("。费用项：")
                    .append(String.join(",", params.getExportFeeNames())).append("。总金额：").append(sumText.toString());
        } else {
            Set<String> carrierNames = new HashSet<>();
            String name;
            for (GhOrderDto dto : dtos) {
                name = dto.getCarrierName();
                String[] names = name.split(",");
                carrierNames.addAll(Arrays.asList(names));
            }
            description.append("机构：").append(String.join(",", orgNames)).append("。供应商：").append(String.join(",", carrierNames)).append("。费用项：")
                    .append(String.join(",", params.getExportFeeNames())).append("。总金额：").append(sumText.toString());
        }
        exportLog.setColumns(description.toString());
        exportLog.setTableName(params.getTableName());
        exportLog.setType(params.getType());
        exportLog.setUserId(params.getUserId());
        exportLog.setFileName(new File(params.getExcelPath()).getName());
        exportLog.setIds(dtos.stream().map(GhOrderDto::getId).collect(Collectors.joining(",")));
        exportLogService.create(exportLog);
        return Result.success(dtos);
    }

    @PostMapping("exportByType3")
    public Result<String> exportByType3(@RequestBody QueryDto params) throws Exception {
        Map<String, String> fieldMap = GhOrderDto.getFieldMap();
        String columns = customColumnsService.getColumnsByUser(params.getUserId(), params.getTableName());
        Assert.isTrue(StringUtils.hasText(columns), "请先保存自定义列再导出");
        List<String> feeNameList = customColumnsService.getFeeNameList();
        params.setFieldMap(fieldMap);
        params.setFeeNames(feeNameList);
        params.setExportColumns(columns);
        // 额外信息
        String yearMonth = LocalDate.now().format(dateTimeFormatter3);
        String exportProfitType;
        if (TypeStringUtils.feeInType.equals(params.getType())) {
            BankInfo bankInfo = bankInfoRepository.findFirstById(params.getBankInfoId());
            exportProfitType = "exportGhOrderReceivable";
            params.getExt().put("bankAccountName", "深圳星达国际供应链科技有限公司");
            params.getExt().put("company1Eng", "Shenzhen Cinda International Supply Chain Technology Co., Ltd.");
            // 公司名称
            params.getExt().put("rmbCompany", bankInfo.getMark());
            params.getExt().put("usdCompany", "");
            // 开户行
            params.getExt().put("rmbBankName", bankInfo.getRmbBankName());
            params.getExt().put("usdBankName", bankInfo.getUsdBankName());
            // 账号
            params.getExt().put("rmbBankAccount", bankInfo.getRmbAccount());
            params.getExt().put("usdBankAccount", bankInfo.getUsdAccount());
        } else {
            exportProfitType = "exportGhOrderPayable";
        }
        int count = exportCountService.getNextNumber(yearMonth, exportProfitType);
        params.getExt().put("invoiceNo", yearMonth + String.format("%03d", count));
        params.getExt().put("date", LocalDate.now().format(dateTimeFormatter));
        // 汇率
        if (!TypeStringUtils.unTransfer.equals(params.getCurrency()) && params.getRateList() != null) {
            List<String> rateStrList = new ArrayList<>();
            params.getRateList().forEach(ex -> {
                if (ex.getToRate().equals(params.getCurrency())) {
                    if (!rateStrList.contains(ex.getRate() + "")) {
                        rateStrList.add(ex.getRate() + "");
                    }
                }
            });
            if (rateStrList.size() > 0) {
                params.setRate(rateStrList.get(0));
            }
        }
        // 保存导出记录
        String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String fileName = "账单-" + date + ".xlsx";
        params.setExcelPath(filePath + "\\" + fileName);
        params.setApi("http://localhost:9045/api/ghOrder/exportByTypeQuery");
        System.out.println(GsonUtil.toJsonString(objectMapper.writeValueAsString(params)));
        //这个方法是类似隐形开启了命令执行器，输入指令执行python脚本
        Process process = Runtime.getRuntime()
                .exec(pythonPath + " " + executeFilePath + " " + GsonUtil.toJsonString(objectMapper.writeValueAsString(params)));
        //这种方式获取返回值的方式是需要用python打印输出，然后java去获取命令行的输出，在java返回
        InputStreamReader ir = new InputStreamReader(process.getInputStream(), UTF_8);
        LineNumberReader input = new LineNumberReader(ir);
        String filePath = input.readLine();
        input.close();
        ir.close();
        process.waitFor();
        if (filePath == null) {
            return Result.fail("生成报表失败");
        }
        return Result.success(new File(filePath).getName());
    }


    public static void main(String[] args) throws Exception {
        QueryDto queryDto = new QueryDto();
        queryDto.setPickDateStart(LocalDate.now());
        queryDto.setPickDateEnd(LocalDate.now());
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        objectMapper.registerModule(javaTimeModule);
        System.out.println(GsonUtil.toJsonString(objectMapper.writeValueAsString(queryDto)));
    }

    @GetMapping("exportLog/{table}/{type}/{userId}")
    public Result<List<ExportLog>> exportLog(@PathVariable String table, @PathVariable String type, @PathVariable String userId) {
        return Result.success(exportLogService.findByUser(table, type, userId));
    }

    @PostMapping("invoiceOrder")
    @OperationLogAnnotation(operDesc = "修改综合物流订单", operModel = "综合物流")
    public Result<String> invoiceOrder(@RequestBody OperateOrderDto operateOrderDto) {
        ghOrderService.invoiceOrder(operateOrderDto);
        return Result.success();
    }

    @PostMapping("settlementOrder")
    @OperationLogAnnotation(operDesc = "修改综合物流订单", operModel = "综合物流")
    public Result<String> settlementOrder(@RequestBody OperateOrderDto operateOrderDto) {
        ghOrderService.settlementOrder(operateOrderDto);
        return Result.success();
    }

    private void outputFile(String fileName, HttpServletResponse response) throws Exception {
        File file = new File(filePath, fileName);
        String fName = URLEncoder.encode(fileName);
        response.setHeader("Content-Disposition", "attachment;filename=" + fName);
        // 发送给客户端的数据
        OutputStream outputStream = response.getOutputStream();
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            int i = bis.read(buff);
            while (i != -1) {
                outputStream.write(buff, 0, buff.length);
                outputStream.flush();
                i = bis.read(buff);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (bis != null) {
                bis.close();
            }
            outputStream.close();
        }
    }


    @PostMapping("download")
    public void download(@RequestParam String fileName, HttpServletResponse response) throws Exception {
        outputFile(fileName, response);
    }


    @PostMapping("downloadFeeExcel")
    @OperationLogAnnotation(operDesc = "导出综合物流订单费用记录", operModel = "综合物流")
    public void downloadFeeExcel(HttpServletResponse response) {
        List<String> columns = new ArrayList<>();
        columns.add("订单编号");
        List<FeeItem> feeItems = feeItemRepository.findAll();
        List<String> feeNames = feeItems.stream().map(FeeItem::getName).collect(Collectors.toList());
        for (String feeName : feeNames) {
            columns.add(String.format("%s币种", feeName));
            columns.add(feeName);
        }
        HSSFWorkbook wb = new HSSFWorkbook();
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            // 生成应收sheet
            HSSFSheet sheet = wb.createSheet("应收");
            sheet.setDefaultColumnWidth(20);// 默认列宽
            HSSFRow row = sheet.createRow(0);
            HSSFCellStyle style = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            HSSFCell cell;
            // 生成标题
            int size = columns.size();
            for (int i = 0; i < size; i++) {
                cell = row.createCell((short) i);
                cell.setCellValue(columns.get(i));
                cell.setCellStyle(style);
            }
            // 生成应付sheet
            columns = new ArrayList<>();
            columns.add("订单编号");
            for (FeeItem feeItem : feeItems) {
                columns.add(feeItem.getName() + "供应商");
                columns.add(String.format("%s币种", feeItem.getName()));
                columns.add(feeItem.getName());
            }
            HSSFSheet sheet2 = wb.createSheet("应付");
            sheet2.setDefaultColumnWidth(20);// 默认列宽
            HSSFRow row2 = sheet2.createRow(0);
            HSSFCellStyle style2 = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            HSSFCell cell2;
            // 生成标题
            int size2 = columns.size();
            for (int i = 0; i < size2; i++) {
                cell2 = row2.createCell((short) i);
                cell2.setCellValue(columns.get(i));
                cell2.setCellStyle(style2);
            }
            // 下载EXCEL
            String fName = URLEncoder.encode("综合物流费用导入-" + LocalDateTime.now().format(dateTimeFormatter2), "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fName + ".xls");
            wb.write(out);
            out.flush();
        } catch (Exception ignored) {

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    @PostMapping("/importFee/{opId}")
    @OperationLogAnnotation(operDesc = "导入综合物流订单费用", operModel = "综合物流")
    public Result<?> orderImportFee(@RequestParam("file") MultipartFile file, @PathVariable String opId) throws Exception {
        // 导入错误信息列表
        Set<String> messageList = new HashSet<>();
        // 解析每行结果在listener中处理
        InputStream inputStream = file.getInputStream();
        Workbook workbook = new HSSFWorkbook(inputStream);
        org.apache.poi.ss.usermodel.Sheet firstSheet = workbook.getSheetAt(0);
        // 获取列头
        List<String> titleList = new ArrayList<>();
        //获取第一行
        Row row = firstSheet.getRow(0);
        int o = 0;
        Iterator<Cell> it = row.iterator();
        Cell cell;//验证文件格式
        while (it.hasNext()) {
            cell = it.next();
            o++;
            if (cell == null) continue;
            String column = String.valueOf(cell);
            titleList.add(column);
        }
        // 用一个字典来存读出来的每一行数据
        List<Map<String, String>> dataList = new ArrayList<>();
        int firstRowIndex = 1;
        int totalRows = firstSheet.getLastRowNum();
        int columnSize = titleList.size();
        while (firstRowIndex <= totalRows) {
            Map<String, String> dataMap = new HashMap<>();
            try {
                row = firstSheet.getRow(firstRowIndex);
                for (int i = 0; i < columnSize; i++) {
                    cell = row.getCell(i);
                    String column = String.valueOf(cell);
                    dataMap.put(titleList.get(i), column);
                }
                firstRowIndex++;
                dataList.add(dataMap);
            } catch (Exception exception) {
                exception.printStackTrace();
                break;
            }
        }
        if (dataList.size() > 0) {
            // 生成应收费用
            Set<String> messages = ghOrderService.batchCreateInFee(dataList);
            if (messages.size() > 0) {
                messageList.addAll(messages);
            }
        }
        //处理应付
        dataList.clear();
        org.apache.poi.ss.usermodel.Sheet secondSheet = workbook.getSheetAt(1);
        titleList = new ArrayList<>();
        //获取第一行
        row = secondSheet.getRow(0);
        o = 0;
        it = row.iterator();
        while (it.hasNext()) {
            cell = it.next();
            o++;
            if (cell == null) continue;
            String column = String.valueOf(cell);
            titleList.add(column);
        }
        firstRowIndex = 1;
        totalRows = secondSheet.getLastRowNum();
        columnSize = titleList.size();
        while (firstRowIndex <= totalRows) {
            try {
                Map<String, String> dataMap = new HashMap<>();
                row = secondSheet.getRow(firstRowIndex);
                for (int i = 0; i < columnSize; i++) {
                    cell = row.getCell(i);
                    String column = String.valueOf(cell);
                    dataMap.put(titleList.get(i), column);
                }
                firstRowIndex++;
                dataList.add(dataMap);
            } catch (Exception exception) {
                exception.printStackTrace();
                break;
            }
        }
        if (dataList.size() > 0) {
            // 生成应收费用
            Set<String> messages = ghOrderService.batchCreateOutFee(dataList);
            if (messages.size() > 0) {
                messageList.addAll(messages);
            }
        }
        return Result.success(messageList);
    }

    @PostMapping("/importTransportFee/{opId}")
    @OperationLogAnnotation(operDesc = "导入综合物流订单费用明细", operModel = "国际班列")
    public Result<?> importTransportFee(@RequestParam("file") MultipartFile file, @PathVariable String opId) throws Exception {
        // 解析每行结果在listener中处理
        InputStream inputStream = file.getInputStream();
        try {
            GhOrderTransportFeeImportListener listener = new GhOrderTransportFeeImportListener();
            EasyExcelFactory.readBySax(inputStream, new Sheet(1, 1, GhOrderExportVo.class), listener);
            ghOrderService.batchImportFee(listener.getImportDatas(), opId);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return Result.success();
    }

    @PostMapping("unSetOrder/{type}")
    @OperationLogAnnotation(operDesc = "修改综合物流订单", operModel = "综合物流")
    public Result<String> unSetOrder(@RequestBody List<String> orderIds, @PathVariable String type) {
        ghOrderService.unSetOrder(orderIds, type);
        return Result.success();
    }
}
